package com.ocom.webapi.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ocom.common.constant.WebApiServiceUrl;
import com.ocom.common.entity.master.EntityCompanyPart;
import com.ocom.common.enums.ResultEnum;
import com.ocom.common.request.company.GetCompanySummaryRequest;
import com.ocom.common.request.company.SetUnitParaRequest;
import com.ocom.common.request.payconfig.SubsidyListRequest;
import com.ocom.common.request.web.FinancialUnitListRequest;
import com.ocom.common.request.web.SubDbMonthlyRequest;
import com.ocom.common.request.web.UnitMonthlyRequest;
import com.ocom.common.resp.Result;
import com.ocom.common.utils.DateUtils;
import com.ocom.common.utils.ResultUtil;
import com.ocom.common.vo.company.SubDbCurrentDataVo;
import com.ocom.common.vo.company.UnitCurrentDataVo;
import com.ocom.common.vo.recode.ConRecCountVo;
import com.ocom.common.vo.recode.MjRecCountVo;
import com.ocom.redis.util.RedisUtil;
import com.ocom.webapi.feign.CompanyClientService;
import com.ocom.webapi.feign.MjRecodeClientService;
import com.ocom.webapi.feign.XfRecordFeign;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Description: 售后
 * @Author: 朱晖
 * @Date: 2023/4/7
 **/
@RestController
@PreAuthorize("@pms.hasRole('ROLE_WEB')" )
public class FinancialController {

	@Autowired
	CompanyClientService companyClientService;

	@Autowired
	XfRecordFeign xfRecordFeign;

	@Autowired
	MjRecodeClientService mjRecodeClientService;

	@Resource
	private RedisUtil redisUtil;

	@PostMapping(WebApiServiceUrl.Url_FinancialUnitList)
	public Result UnitList(@RequestBody FinancialUnitListRequest request) {
		if (request.getPage() < 1 || request.getSize() < 1) {
			return ResultUtil.error(ResultEnum.Err_3076);
		}
		GetCompanySummaryRequest getCompanySummaryRequest = new GetCompanySummaryRequest();
		getCompanySummaryRequest.setOnlyCom(1);
		if (request.getComId() == null) {
			getCompanySummaryRequest.setComId(-1);
		} else {
			getCompanySummaryRequest.setComId(request.getComId().intValue());
		}
		if (request.getAgentId() == null) {
			getCompanySummaryRequest.setAgentId(-1);
		} else {
			getCompanySummaryRequest.setAgentId(request.getAgentId());
		}
		if (request.getComStatus() == null) {
			getCompanySummaryRequest.setComStatus(-1);
		} else {
			getCompanySummaryRequest.setComStatus(request.getComStatus());
		}
		getCompanySummaryRequest.setComName(request.getComName());
		getCompanySummaryRequest.setSaasNo(request.getSaasNo());
		getCompanySummaryRequest.setPage(request.getPage());
		getCompanySummaryRequest.setSize(request.getSize());
		getCompanySummaryRequest.setXfVer(-1);
		getCompanySummaryRequest.setMjVer(-1);
		getCompanySummaryRequest.setSubDb(0);
		Result result = companyClientService.getCompanySummary(getCompanySummaryRequest);
		if (result.getCode() != 200) {
			return result;
		}

		JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(result.getData()));
		if (jsonObject.getInteger("total") == 0) {
			return result;
		}

		List<JSONObject> parseArray = JSON.parseArray(JSON.toJSONString(jsonObject.get("list")), JSONObject.class);

		//获取分库范围
		Result result1 = companyClientService.getSubDbComId(0);
		List<EntityCompanyPart> companyPartList = JSON.parseArray(JSON.toJSONString(result1.getData()), EntityCompanyPart.class);

		//当前页的需要查的所有分片
		List<Integer> parts = new ArrayList<>();

//		for (JSONObject jsonObject2 : parseArray) {
		for (int i = 0; i < parseArray.size(); i++) {
			JSONObject jsonObject2 = parseArray.get(i);

			jsonObject2.put("subDb", 0);
			Long comId = jsonObject2.getLong("comId");
			for (EntityCompanyPart entityCompanyPart : companyPartList) {
				if (comId.compareTo(entityCompanyPart.getBeginComId()) >= 0 &&
						comId.compareTo(entityCompanyPart.getEndComId()) <= 0
				) {
					jsonObject2.put("subDb", entityCompanyPart.getPart());
					parseArray.set(i, jsonObject2);
					if (!parts.contains(entityCompanyPart.getPart())) {
						parts.add(entityCompanyPart.getPart());
						continue;
					}
				}
			}
		}

		List<UnitCurrentDataVo> list = new ArrayList<>();

		for (Integer part : parts) {
			Result result2 = companyClientService.getUnitCurrentData(part);
			if (result2.getCode() == 200) {
				List<UnitCurrentDataVo> list3 = JSON.parseArray(JSON.toJSONString(result2.getData()), UnitCurrentDataVo.class);
				list.addAll(list3);
			}
		}

		//list转map
		Map<Long, UnitCurrentDataVo> map = list.stream()
				.collect(Collectors.toMap(UnitCurrentDataVo::getComId, Function.identity()));


		for (int i = 0; i < parseArray.size(); i++) {
			JSONObject jsonObject2 = parseArray.get(i);

			Long comId = jsonObject2.getLong("comId");

			jsonObject2.put("nowUserNum", 0);
			jsonObject2.put("nowXfMachNum", 0);
			jsonObject2.put("nowMjMachNum", 0);
			jsonObject2.put("nowTableNum", 0);
			jsonObject2.put("nowChannelNum", 0);
			jsonObject2.put("xfRecNum", 0);
			jsonObject2.put("mjRecNum", 0);
			jsonObject2.put("mjRecNum", 0);


//			nowUserNum	当前用户数	int
//			nowXfMachNum	当前消费设备数	int
//			nowMjMachNum	当前门禁设备数	int
//			nowTableNum	当前取餐点数	int
//			nowChannelNum	当前支付通道数	int
//			xfRecNum	上月消费记录数	int
//			mjRecNum	上月门禁记录数	int

			if (map.containsKey(comId)) {
				jsonObject2.put("nowUserNum", map.get(comId).getNowUserNum());
				jsonObject2.put("nowXfMachNum", map.get(comId).getNowXfMachNum());
				jsonObject2.put("nowMjMachNum", map.get(comId).getNowMjMachNum());
				jsonObject2.put("nowTableNum", map.get(comId).getNowTableNum());
				jsonObject2.put("nowChannelNum", map.get(comId).getNowChannelNum());
				jsonObject2.put("xfRecNum", map.get(comId).getXfRecNum());
				jsonObject2.put("mjRecNum", map.get(comId).getMjRecNum());
			}
			parseArray.set(i, jsonObject2);
		}


		Map<String,Object>  resmap =new HashMap<>();
		resmap.put("total",	jsonObject.getInteger("total"));
		resmap.put("list",	parseArray);
		return ResultUtil.success(resmap);
	}

	@PostMapping(WebApiServiceUrl.Url_FinancialUnitMonthly)
	public Result UnitMonthly(@RequestBody UnitMonthlyRequest request) throws Exception {

		if (request.getStartTime().length() > 6) {
			request.setStartTime(request.getStartTime().replace("-", "").substring(0, 6));
		}
		if (request.getEndTime().length() > 6) {
			request.setEndTime(request.getEndTime().replace("-", "").substring(0, 6));
		}
		String beginMonth = request.getStartTime();

		List<String> stringList = DateUtils.getMonthBetween(request.getStartTime(), request.getEndTime());

		List<JSONObject> list = new ArrayList<>();

		//是否需要查询
		Boolean flag = false;

		for (int i = stringList.size()-1 ; i >-1 ; i--) {
			JSONObject jsonObject1 = new JSONObject();

			/**
			 * yearMonth	年月	string	yyyy-MM
			 * userNum	消费用户数	Int
			 * amount	消费金额	int	以分为单位，正数
			 * xfMachNum	消费设备数	int
			 * xfRecNum	消费记录数	int
			 * mjMachNum	门禁设备数	int
			 * mjRecNum	门禁记录数	int
			 */
			jsonObject1.put("yearMonth", DateUtils.getLastMonth(request.getEndTime(), i));

			String key = "UnitMonthly:"+request.getComId()+":"+jsonObject1.getString("yearMonth");
			Object secObj  = redisUtil.get(key);
			if(secObj!=null){
				//不是最后一个
				if(i!=0){
					beginMonth = DateUtils.getLastMonth(request.getEndTime(), i-1);
				}
				jsonObject1 = (JSONObject) secObj;
			}else{
				flag=true;
				jsonObject1.put("userNum", 0);
				jsonObject1.put("amount", 0);
				jsonObject1.put("xfMachNum", 0);
				jsonObject1.put("xfRecNum", 0);
				jsonObject1.put("mjMachNum", 0);
				jsonObject1.put("mjRecNum", 0);
			}
			list.add(jsonObject1);
		}


		if(flag){
			Result result = xfRecordFeign.getConsMonthData(request.getComId(), beginMonth, request.getEndTime());

			if (result.getData() != null) {
				List<ConRecCountVo> conRecCountVos = JSON.parseArray(JSON.toJSONString(result.getData()), ConRecCountVo.class);
				for (ConRecCountVo conRecCountVo : conRecCountVos) {
					for (int i = 0; i < list.size(); i++) {
						JSONObject jsonObject = list.get(i);
						if (jsonObject.getString("yearMonth").equals(conRecCountVo.getMonthValue())) {
							jsonObject.put("userNum", conRecCountVo.getUserNum());
							jsonObject.put("amount", conRecCountVo.getAmount());
							jsonObject.put("xfMachNum", conRecCountVo.getXfMachNum());
							jsonObject.put("xfRecNum", conRecCountVo.getXfRecNum());
							list.set(i, jsonObject);
						}
					}
				}
			}

			Result result2 = mjRecodeClientService.getAccessMonthData(request.getComId(), beginMonth, request.getEndTime());

			if (result2.getData() != null) {
				List<MjRecCountVo> mjRecCountVos = JSON.parseArray(JSON.toJSONString(result2.getData()), MjRecCountVo.class);
				for (MjRecCountVo mjRecCountVo : mjRecCountVos) {
					for (int i = 0; i < list.size(); i++) {
						JSONObject jsonObject = list.get(i);
						if (jsonObject.getString("yearMonth").equals(mjRecCountVo.getMonthValue())) {
							jsonObject.put("mjMachNum", mjRecCountVo.getMjMachNum());
							jsonObject.put("mjRecNum", mjRecCountVo.getMjRecNum());
							list.set(i, jsonObject);
						}
					}
				}
			}

			String currentMonthValue  = DateUtils.getStrDate(new Date(),"yyyyMM");
			currentMonthValue = DateUtils.getLastMonth(currentMonthValue, 1);
			for (int i = 0; i < list.size(); i++) {
				JSONObject jsonObject = list.get(i);
				if (jsonObject.getString("yearMonth").compareTo(currentMonthValue)<0) {
					redisUtil.set("UnitMonthly:"+request.getComId()+":"+jsonObject.getString("yearMonth"),jsonObject);
				}
			}
		}


		return ResultUtil.success(list);
	}

	@PostMapping(WebApiServiceUrl.Url_FinancialModifyUnitPara)
	public Result ModifyUnitPara(@RequestBody SetUnitParaRequest request) {
		return companyClientService.setUnitPara(request);
	}

	@PostMapping(WebApiServiceUrl.Url_FinancialSubDbList)
	public Result SubDbList() {
		//获取分库范围
		Result result1 = companyClientService.getSubDbComId(0);
		List<EntityCompanyPart> companyPartList = JSON.parseArray(JSON.toJSONString(result1.getData()), EntityCompanyPart.class);

		/**
		 * 调用接口3.0微服务-单位5.5 getSubDbCurrentData（参数beginComId、endComId）获取list
		 * 消费配置6.2.2 getSubDbConsRecNum（参数beginComId、endComId、month=上月）获取单位消费记录数，合并到list。
		 * 3.0微服务-门禁2.3.4 getSubDbAccessRecNum（参数beginComId、endComId、month=上月）获取单位门禁记录数，合并到list。
		 */

		/**
		 * unitTotal	单位总数	int
		 * normalUnit	正常	Int
		 * sampleUnit	测试	int
		 * testUnit	试用	int
		 * overUnit	逾期	int
		 * stopUnit	停用	int
		 * nowUserNum	当前用户数	int	默认填0
		 * nowXfMachNum	当前消费设备数	int	默认填0
		 * nowMjMachNum	当前门禁设备数	int	默认填0
		 * nowTableNum	当前取餐点数	int	默认填0
		 * xfRecNum	上月消费记录数	int	默认填0
		 * mjRecNum	上月门禁记录数	int	默认填0
		 * part 某分库
		 */

		String month = DateUtils.getLastMonth().replace("-", "");

		List<JSONObject> list = new ArrayList<>();
		for (EntityCompanyPart entityCompanyPart : companyPartList) {

			JSONObject jsonObject1 = new JSONObject();
			jsonObject1.put("subDb", entityCompanyPart.getPart());
			jsonObject1.put("unitTotal", 0);
			jsonObject1.put("normalUnit", 0);
			jsonObject1.put("sampleUnit", 0);
			jsonObject1.put("testUnit", 0);
			jsonObject1.put("stopUnit", 0);
			jsonObject1.put("overUnit", 0);
			jsonObject1.put("nowUserNum", 0);
			jsonObject1.put("nowTableNum", 0);
			jsonObject1.put("nowXfMachNum", 0);
			jsonObject1.put("nowMjMachNum", 0);
			jsonObject1.put("xfRecNum", 0);
			jsonObject1.put("mjRecNum", 0);

			Result result2 = companyClientService.getSubDbCurrentData(entityCompanyPart.getPart());
			if (result2.getCode() == 200) {
				SubDbCurrentDataVo dataVo = JSONObject.parseObject(JSON.toJSONString(result2.getData()), SubDbCurrentDataVo.class);
				jsonObject1.put("unitTotal", dataVo.getUnitTotal());
				jsonObject1.put("normalUnit", dataVo.getNormalUnit());
				jsonObject1.put("sampleUnit", dataVo.getSampleUnit());
				jsonObject1.put("testUnit", dataVo.getTestUnit());
				jsonObject1.put("stopUnit", dataVo.getStopUnit());
				jsonObject1.put("overUnit", dataVo.getOverUnit());
				jsonObject1.put("nowUserNum", dataVo.getNowUserNum());
				jsonObject1.put("nowTableNum", dataVo.getNowTableNum());
				jsonObject1.put("nowXfMachNum", dataVo.getNowXfMachNum());
				jsonObject1.put("nowMjMachNum", dataVo.getNowMjMachNum());
			}

			Result result3 = xfRecordFeign.getSubDbConsRecNum(entityCompanyPart.getBeginComId(), entityCompanyPart.getEndComId(), month);
			if (result3.getCode() == 200) {
				Map<String, Object> resmap = JSONObject.parseObject(JSON.toJSONString(result3.getData()), Map.class);
				jsonObject1.put("xfRecNum", resmap.get("xfRecNum"));
			}

			Result result4 = mjRecodeClientService.getSubDbAccessRecNum(entityCompanyPart.getBeginComId(), entityCompanyPart.getEndComId(), month);
			if (result4.getCode() == 200) {
				Map<String, Object> resmap2 = JSONObject.parseObject(JSON.toJSONString(result4.getData()), Map.class);
				jsonObject1.put("mjRecNum", resmap2.get("mjRecNum"));
			}
			list.add(jsonObject1);
		}

		return ResultUtil.success(list);
	}

	@PostMapping(WebApiServiceUrl.Url_FinancialSubDbMonthly)
	public Result SubDbMonthly(@RequestBody SubDbMonthlyRequest request) {

		String endMonth = DateUtils.getDate().replace("-", "").substring(0, 6);
		String beginMonth = DateUtils.getLastMonth(endMonth, 13);

		/**
		 * 消费配置6.2.4 getSubDbConsMonthData（参数beginComId、endComId）获取分库消费月数据，获取list。
		 * 3.0微服务-门禁2.3.6 getAccessConsMonthData（参数beginComId、endComId）获取分库门禁月数据，合并到list。
		 */

		/**
		 * yearMonth	年月	string	yyyy-MM
		 * userNum	消费用户数	Int
		 * amount	消费金额	int	以分为单位，正数
		 * xfMachNum	消费设备数	int
		 * xfRecNum	消费记录数	int
		 * mjMachNum	门禁设备数	int
		 * mjRecNum	门禁记录数	int
		 */

		List<JSONObject> list = new ArrayList<>();

		for (int i = 0; i < 13; i++) {
			JSONObject jsonObject1 = new JSONObject();
			/**
			 * yearMonth	年月	string	yyyy-MM
			 * userNum	消费用户数	Int
			 * amount	消费金额	int	以分为单位，正数
			 * xfMachNum	消费设备数	int
			 * xfRecNum	消费记录数	int
			 * mjMachNum	门禁设备数	int
			 * mjRecNum	门禁记录数	int
			 */
			jsonObject1.put("yearMonth", DateUtils.getLastMonth(endMonth, i));
			jsonObject1.put("userNum", 0);
			jsonObject1.put("amount", 0);
			jsonObject1.put("xfMachNum", 0);
			jsonObject1.put("xfRecNum", 0);
			jsonObject1.put("mjMachNum", 0);
			jsonObject1.put("mjRecNum", 0);
			list.add(jsonObject1);
		}

		Result result1 = companyClientService.getSubDbComId(request.getSubDb());
		EntityCompanyPart companyPart = JSON.parseObject(JSON.toJSONString(result1.getData()), EntityCompanyPart.class);


		Result result2 = xfRecordFeign.getSubDbConsMonthData(companyPart.getBeginComId(), companyPart.getEndComId(), beginMonth, endMonth);

		if (result2.getCode() == 200) {
			List<ConRecCountVo> conRecCountVos = JSONObject.parseArray(JSON.toJSONString(result2.getData()), ConRecCountVo.class);
			for (ConRecCountVo conRecCountVo : conRecCountVos) {
				for (int i = 0; i < list.size(); i++) {
					JSONObject jsonObject = list.get(i);
					if (jsonObject.getString("yearMonth").equals(conRecCountVo.getMonthValue())) {
						jsonObject.put("userNum", conRecCountVo.getUserNum());
						jsonObject.put("amount", conRecCountVo.getAmount());
						jsonObject.put("xfMachNum", conRecCountVo.getXfMachNum());
						jsonObject.put("xfRecNum", conRecCountVo.getXfRecNum());
						list.set(i, jsonObject);
					}
				}
			}
		}


		Result result3 = mjRecodeClientService.getSubDbAccessMonthData(companyPart.getBeginComId(), companyPart.getEndComId(), beginMonth, endMonth);

		if (result3.getCode() == 200) {
			List<MjRecCountVo> mjRecCountVos = JSONObject.parseArray(JSON.toJSONString(result3.getData()), MjRecCountVo.class);
			for (MjRecCountVo conRecCountVo : mjRecCountVos) {
				for (int i = 0; i < list.size(); i++) {
					JSONObject jsonObject = list.get(i);
					if (jsonObject.getString("yearMonth").equals(conRecCountVo.getMonthValue())) {
						jsonObject.put("mjMachNum", conRecCountVo.getMjMachNum());
						jsonObject.put("mjRecNum", conRecCountVo.getMjRecNum());
						list.set(i, jsonObject);
					}
				}
			}
		}
		return ResultUtil.success(list);
	}

	@PostMapping(WebApiServiceUrl.Url_FinancialExportSubDbUnit)
	public Result ExportSubDbUnit(@RequestBody SubsidyListRequest subsidyListRequest) {
		return null;
	}


}
